#include "StdMyString.h"
#include <cstring>
#include <cstdlib>


StdMyString::StdMyString()
{
    size=10;
    str=new char[10];
    len=0;
    memset(str,0,10);
}

StdMyString::StdMyString(const char *str)
{
    len=strlen(str);
    size=(len/10+1)*10;
    this->str=new char[size];
    strcpy(this->str,str);
}

StdMyString::StdMyString(const StdMyString &str)
{
    len=str.len;
    size=str.size;
    this->str=new char[size];
    strcpy(this->str,str.str);
}
StdMyString::~StdMyString()
{
    delete str;
}



char StdMyString::At(int index)
{
    if(index<0||index>=len)
    {
        std::cout<<"At :invalid index :"<<index<<std::endl;
        return -1;
    }
    else
    {
        return str[index];
    }
}

bool StdMyString::Contains(const char *str)
{
    if(strstr(this->str,str)==NULL)
        return false;
    else
        return true;
}

bool StdMyString::Contains(const StdMyString &str)
{
    return Contains(str.str);
}
int StdMyString::Find(const char *str)
{
    char *ptr=strstr(this->str,str);
    if(ptr==nullptr)
        return -1;
    else
        return ptr-this->str;
}
int StdMyString::Find(const StdMyString &str)
{
    return Find(str.str);
}
StdMyString StdMyString::GetString(int start, int end)
{
    if(start>=0||start<end||end<=len)
    {
        StdMyString s;
        delete s.str;
        s.len=end-start;
        s.size=(s.len/10+1)*10;
        s.str=new char[s.size];
        strncpy(s.str,this->str+start,s.len);
        s.str[s.len]='\0';
        return s;
    }
    return StdMyString();
}
void StdMyString::InsertByIndex(const char *str, int index)
{
    if(index<0||index>len)
    {
        std::cout<<"InsertByIndex:invalid index :"<<index<<std::endl;
        return;
    }
    char *newstr=new char [len+strlen(str)+1];
    sprintf(newstr,"%s%s%s",this->GetString(0,index).str,str,this->GetString(index,len).str);
    delete this->str;
    this->str=newstr;
    this->len=strlen(this->str);
    this->size=(this->len/10+1)*10;
}
void StdMyString::InsertByIndex(const StdMyString &str, int index)
{
    this->InsertByIndex(str.str,index);
}

StdMyString StdMyString::Number(int num)
{
    StdMyString s;
    sprintf(s.str,"%d",num);
    s.len=strlen(s.str);
    return s;
}
StdMyString StdMyString::Number(float num)
{
    StdMyString s;
    sprintf(s.str,"%f",num);
    s.len=strlen(s.str);
    return s;
}
StdMyString::operator int()
{
    return atoi(this->str);
}
StdMyString::operator float()
{
    return atof(this->str);
}

char &StdMyString::operator[](int index)
{
    if(index<0||index>=len)
    {
        std::cout<<"operator[]:invalid index :"<<index<<std::endl;
        return this->str[len+1];
    }
    else
    {
        return str[index];
    }
}
StdMyString &StdMyString::operator=(const StdMyString &str)
{
    // printf("const StdMyString &str\n");
    this->size=str.size;
    this->len=str.len;
    delete this->str;
    this->str=new char[this->size];
    strcpy(this->str,str.str);
    return *this;
}
StdMyString &StdMyString::operator=(const char *str)
{
    // printf("const char *str\n");
    delete this->str;
    len=strlen(str);
    size=(len/10+1)*10;
    this->str=new char[size];
    strcpy(this->str,str);
    return *this;
}
StdMyString StdMyString::operator+(const char *str)
{
    StdMyString newstr;
    delete newstr.str;
    newstr.len=this->len+strlen(str);
    newstr.size=(newstr.len/10+1)*10;
    newstr.str=new char[newstr.size];
    strcpy(newstr.str,this->str);
    strcat(newstr.str,str);
    return newstr;
}
StdMyString StdMyString::operator+(const StdMyString &str)
{
    return *this+(const char*)str.str;
}
void StdMyString::operator+=(const char *str)
{
    if(this->size>=strlen(str)+this->len)
    {
        strcat(this->str,str);
        this->len+=strlen(str);
    }
    else
    {
        this->len+=strlen(str);
        this->size=(this->len/10+1)*10;
        char *newstr=new char[this->size];
        strcpy(newstr,this->str);
        strcat(newstr,str);
        delete this->str;
        this->str=newstr;
    }
}
void StdMyString::operator+=(const StdMyString &str)
{
    *this+=str.str;
}


bool StdMyString::operator==(const char *str)
{
    if(strcmp(this->str,str)==0)
        return true;
    else
        return false;
}
bool StdMyString::operator==(const StdMyString &str)
{
    return *this==str.str;
}

bool StdMyString::operator!=(const char *str)
{
    return !(*this==str);
}
bool StdMyString::operator!=(const StdMyString &str)
{
    return !(*this==str);
}
bool StdMyString::operator>(const char *str)
{
    if(strcmp(this->str,str)>0)
        return true;
    else
        return false;
}
bool StdMyString::operator>(const StdMyString &str)
{
    return *this>str.str;
}

bool StdMyString::operator<(const char *str)
{
    if(strcmp(this->str,str)<0)
        return true;
    else
        return false;
}
bool StdMyString::operator<(const StdMyString &str)
{
    return *this<str.str;
}
std::ostream& operator<<(std::ostream& out, const StdMyString& str)
{
    out<<str.str;
    return out;
}